<!DOCTYPE html>
<html>

<head>
    <title>Camera Stream</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f0f0f0;
        }

        .container {
            max-width: 100%;
            margin: 0 auto;
            background-color: white;
            border-radius: 10px;
            padding: 20px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }

        h1 {
            text-align: center;
            color: #333;
            font-size: 1.5em;
            margin-top: 0;
        }

        #video,
        #canvas {
            width: 100%;
            max-width: 100%;
            height: auto;
            border-radius: 8px;
            background-color: #000;
        }

        #canvas {
            display: none;
        }

        .button-container {
            display: flex;
            gap: 10px;
            margin: 20px 0;
            justify-content: center;
        }

        button {
            flex: 1;
            padding: 12px 20px;
            font-size: 16px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            transition: background-color 0.3s;
            min-width: 120px;
        }

        #zmBtn {
            background-color: #4CAF50;
            color: white;
        }

        #zmBtn:hover {
            background-color: #45a049;
        }

        #bzBtn {
            background-color: #2196F3;
            color: white;
        }

        #bzBtn:hover {
            background-color: #0b7dda;
        }

        #stopBtn {
            background-color: #f44336;
            color: white;
        }

        #stopBtn:hover {
            background-color: #da190b;
        }

        #result {
            margin-top: 20px;
            padding: 15px;
            border-radius: 8px;
            background-color: #f9f9f9;
        }

        #result h2 {
            font-size: 1.2em;
            margin-top: 0;
            color: #333;
        }

        #ocrText {
            background-color: #fff;
            padding: 10px;
            border-radius: 4px;
            min-height: 50px;
            white-space: pre-wrap;
            word-wrap: break-word;
            font-family: monospace;
            font-size: 24px;
            line-height: 1.5;
        }

        #ocrImage {
            margin-top: 15px;
            text-align: center;
        }

        #ocrImage img {
            max-width: 100%;
            height: auto;
            border-radius: 4px;
        }

        @media (max-width: 600px) {
            body {
                padding: 10px;
            }

            .container {
                padding: 15px;
            }

            h1 {
                font-size: 1.3em;
            }

            .button-container {
                flex-direction: column;
            }

            button {
                width: 100%;
                margin-bottom: 10px;
            }

            #ocrText {
                font-size: 18px;
            }
        }
    </style>
</head>

<body>
    <div class="container">
        <h1 id="pageTitle">选择题库</h1>
        <div class="button-container">
            <button id="zmBtn" data-type="sz">水闸</button>
            <button id="bzBtn" data-type="bz">泵站</button>
            <button id="stopBtn">停止</button>
        </div>
        <div id="result">
            <h2>识别结果:</h2>
            <pre id="ocrText"></pre>
            <!-- <div id="ocrImage"></div> -->
        </div>
        <video id="video" width="320" height="240" autoplay playsinline muted></video>
        <canvas id="canvas" width="320" height="240"></canvas>
    </div>

    <script>
        let selectedType = null;
        const video = document.getElementById('video');
        const canvas = document.getElementById('canvas');
        const zmBtn = document.getElementById('zmBtn');
        const bzBtn = document.getElementById('bzBtn');
        const stopBtn = document.getElementById('stopBtn');
        const ctx = canvas.getContext('2d');
        const ocrText = document.getElementById('ocrText');
        const ocrImage = document.getElementById('ocrImage');
        const pageTitle = document.getElementById('pageTitle'); // 新增: 页面标题元素

        let stream = null;
        let intervalId = null;
        let isProcessing = false; // 标记是否正在处理

        // 新增: 计时相关变量
        let startTime = null;
        let timerInterval = null;

        // 新增: 语音合成相关变量
        let speechSynthesis = window.speechSynthesis;
        let isSpeaking = false;

        // 新增: 保存上一次识别结果
        let previousResult = '';

        // 新增: iOS检测
        function isiOS() {
            return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
        }

        // 新增: 检查是否支持语音合成
        function isSpeechSynthesisSupported() {
            return 'speechSynthesis' in window;
        }

        // 新增: 用户手势触发函数（用于iOS）
        function initializeAudio() {
            if (isiOS() && isSpeechSynthesisSupported()) {
                // 在iOS上需要用户手势来初始化音频上下文
                const utterThis = new SpeechSynthesisUtterance('');
                speechSynthesis.speak(utterThis);
            }
        }

        // 开始摄像头 - 闸门
        zmBtn.addEventListener('click', async () => {
            // 新增: 初始化音频（iOS支持）
            initializeAudio();
            
            selectedType = 'sz';
            // 修改: 隐藏按钮并更新标题
            zmBtn.style.display = 'none';
            bzBtn.style.display = 'none';
            pageTitle.textContent = '水闸';
            startCamera();
        });

        // 开始摄像头 - 泵站
        bzBtn.addEventListener('click', async () => {
            // 新增: 初始化音频（iOS支持）
            initializeAudio();
            
            selectedType = 'bz';
            // 修改: 隐藏按钮并更新标题
            zmBtn.style.display = 'none';
            bzBtn.style.display = 'none';
            pageTitle.textContent = '泵站';
            startCamera();
        });

        // 开始摄像头通用函数
        async function startCamera() {
            try {
                // 优先使用后置摄像头
                const constraints = {
                    video: {
                        facingMode: 'environment' // 后置摄像头
                    }
                };

                // iOS兼容性处理
                if (isiOS()) {
                    // iOS上可能需要不同的约束条件
                    constraints.video = {
                        facingMode: 'environment',
                        width: { ideal: 1280 },
                        height: { ideal: 720 }
                    };
                }

                stream = await navigator.mediaDevices.getUserMedia(constraints);
                video.srcObject = stream;

                // 每100毫秒检查一次是否可以发送帧
                intervalId = setInterval(captureAndSendFrame, 100);
            } catch (err) {
                console.error("Error accessing camera:", err);
                alert("无法访问摄像头: " + err.message);
            }
        }

        // 新增: 开始计时函数
        function startTimer() {
            startTime = Date.now();
            clearInterval(timerInterval);
            timerInterval = setInterval(() => {
                const elapsed = Date.now() - startTime;
                const seconds = Math.floor(elapsed / 1000);
                const milliseconds = Math.floor((elapsed % 1000) / 10);
                pageTitle.textContent = `处理中... ${seconds}.${milliseconds.toString().padStart(2, '0')}s`;
            }, 10);
        }

        // 新增: 停止计时函数
        function stopTimer() {
            clearInterval(timerInterval);
            timerInterval = null;
            startTime = null;
        }

        // 新增: 文字转语音函数
        function speakText(text) {
            // 检查是否支持语音合成
            if (!isSpeechSynthesisSupported()) {
                console.warn("Speech synthesis not supported");
                return;
            }

            // 如果已经在播放，则先取消
            if (isSpeaking) {
                speechSynthesis.cancel();
            }

            // 修改: 只朗读\n后面的内容
            let textToSpeak = text;
            const newlineIndex = text.indexOf('\n');
            if (newlineIndex !== -1) {
                textToSpeak = text.substring(newlineIndex + 1);
            }
            textToSpeak = textToSpeak.replace('√', '正确').replace('×', '错误');

            // 创建语音合成对象
            let utterThis = new SpeechSynthesisUtterance(textToSpeak);

            // 设置语音属性
            utterThis.lang = 'zh-CN'; // 设置为中文
            utterThis.rate = 1; // 语速
            utterThis.pitch = 1; // 音调

            // 监听开始和结束事件
            utterThis.onstart = function () {
                isSpeaking = true;
                console.log("开始播放语音");
            };

            utterThis.onend = function () {
                isSpeaking = false;
                console.log("语音播放结束");
            };

            utterThis.onerror = function (event) {
                isSpeaking = false;
                console.error("语音播放错误:", event);
            };

            // 播放语音
            speechSynthesis.speak(utterThis);
        }

        // 停止摄像头
        stopBtn.addEventListener('click', () => {
            if (stream) {
                stream.getTracks().forEach(track => track.stop());
                stream = null;
            }
            if (intervalId) {
                clearInterval(intervalId);
                intervalId = null;
            }
            isProcessing = false; // 重置处理状态

            // 新增: 停止计时器
            stopTimer();

            // 新增: 停止语音播放
            if (isSpeaking) {
                speechSynthesis.cancel();
                isSpeaking = false;
            }

            // 修改: 恢复按钮显示并重置标题
            zmBtn.style.display = 'block';
            bzBtn.style.display = 'block';
            pageTitle.textContent = 'Camera Stream';
        });

        // 捕获并发送帧
        function captureAndSendFrame() {
            // 只有在不处理时才捕获新帧
            if (!isProcessing && video.readyState === video.HAVE_ENOUGH_DATA) {
                // 将视频帧绘制到canvas上
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;
                ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

                // 将图像转换为base64编码并发送
                const dataUrl = canvas.toDataURL('image/jpeg');
                sendFrame(dataUrl);
            }
        }

        // 发送帧到服务器
        function sendFrame(dataUrl) {
            // 如果没有选择类型，则不发送
            if (!selectedType) {
                return;
            }

            isProcessing = true; // 设置为正在处理

            // 新增: 开始计时
            startTimer();

            fetch('/webstream', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    image: dataUrl,
                    type: selectedType  // 添加类型参数
                })
            })
                .then(response => response.json())
                .then(data => {
                    if (data.error) {
                        console.error('Failed to process frame:', data.error);
                    } else {
                        // 显示OCR结果
                        const result = data.result;
                        if (result && result.length >= 2) {
                            // 显示识别的文字
                            ocrText.textContent = result;

                            // 修改: 只有识别结果变化时才播放语音
                            if (result !== previousResult) {
                                previousResult = result;
                                speakText(result);
                            }

                            // 显示带框的图像
                            /*if (result[1]) {
                                ocrImage.innerHTML = '';
                                const img = document.createElement('img');
                                img.src = 'data:image/jpeg;base64,' + result[1];
                                img.style.maxWidth = '100%';
                                ocrImage.appendChild(img);
                            }
                            */
                        }
                    }
                })
                .catch(error => {
                    console.error('Error sending frame:', error);
                })
                .finally(() => {
                    // 处理完成后重置标志
                    isProcessing = false;
                    // 新增: 停止计时
                    stopTimer();
                });
        }

        // 页面卸载时停止摄像头
        window.addEventListener('beforeunload', () => {
            stopBtn.click();
        });
    </script>
</body>

</html>